package com.weijing.pretty_app.util

import android.Manifest
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.util.Log
import androidx.core.content.ContextCompat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancelChildren
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.util.UUID

private const val TAG = "BluetoothSocketManager"

object BluetoothSocketManager {

    private const val TAG = "BluetoothSocketManager"
    private var socket: BluetoothSocket? = null
    private var inputStream: InputStream? = null
    private var outputStream: OutputStream? = null

    private val listeners = mutableListOf<(ByteArray) -> Unit>()

    private var isManuallyConnected = false

    // 全局作用域（便于统一取消任务）
    private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
    private var readJob: Job? = null

    /** 连接设备（传 BluetoothDevice，推荐在点击列表时直接把 device 传进来） */
    fun connect(context: Context, device: BluetoothDevice, onResult: (Boolean, String) -> Unit) {
        if (isConnected()) {
            onResult(true, "蓝牙已连接")
            return
        }

        if (!checkBtConnectPermission(context)) {
            Log.i(TAG,"checkBtConnectPermission")
            onResult(false, "缺少连接权限")
            return
        }

        scope.launch {
            try {
                withContext(Dispatchers.Main) {
                    onResult(false, "正在连接，请稍候…")
                    Log.i(TAG,"正在连接，请稍候…")
                }
                BluetoothAdapter.getDefaultAdapter().cancelDiscovery()

                val uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")

                val bluetoothSocket = device.createRfcommSocketToServiceRecord(uuid)

                bluetoothSocket.connect()                  // 阻塞，成功才往下走
                socket = bluetoothSocket
                inputStream = bluetoothSocket.inputStream
                outputStream = bluetoothSocket.outputStream
                isManuallyConnected = true
                startReadingLoop()
                withContext(Dispatchers.Main) {
                    Log.i(TAG, "已连接 -> ${device.name} (${device.address})")
                    onResult(true, "连接成功")
                }
            } catch (e: IOException) {
                e.printStackTrace()
                closeConnection()
                Log.e(TAG, "连接失败: ${e.message}")
                withContext(Dispatchers.Main) {
                    onResult(false, "连接失败：${e.localizedMessage ?: "未知错误"}")
                }
            }
        }
    }

    /** 判断连接状态 */
    private fun isConnected(): Boolean {
        return socket?.isConnected == true && isManuallyConnected
    }

    private fun startReadingLoop() {
        val input = inputStream ?: return
        readJob?.cancel()
        readJob = scope.launch {
            val buffer = ByteArray(1024)
            try {
                while (isActive && isConnected()) {
                    val len = input.read(buffer)
                    if (len > 0) {
                        val data = buffer.copyOf(len)
                        // 分发给监听者
                        listeners.forEach { it.invoke(data) }
                    } else {
                        Log.w(TAG, "read = -1，远端关闭")
                        break
                    }
                }
            } catch (e: IOException) {
                e.printStackTrace()
                Log.e(TAG, "读取异常: ${e.message}")
            }
        }
    }

    /** 发送原始字节数组 */
    fun send(data: ByteArray) {
        if (!isConnected()) {
            Log.w(TAG, "尚未连接，无法发送")
            return
        }
        scope.launch {
            try {
                outputStream?.apply {
                    write(data)
                    flush()
                }
                Log.d(TAG, "指令已发送: ${byteArrayToHexString(data)}")
            } catch (e: IOException) {
                Log.e(TAG, "发送失败: ${e.message}")
            }
        }
    }

    /** 添加数据监听者 */
    fun addDataReceivedListener(listener: (ByteArray) -> Unit) {
        if (!listeners.contains(listener)) listeners.add(listener)
    }

    /** 移除数据监听者 */
    fun removeDataReceivedListener(listener: (ByteArray) -> Unit) {
        listeners.remove(listener)
    }

    /** 清空所有监听器 */
    fun clearAllListeners() {
        listeners.clear()
    }

    /** 断开连接 */
    fun closeConnection() {
        try {
            socket?.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
        socket = null
        inputStream = null
        outputStream = null
        isManuallyConnected = false
        readJob?.cancel()
        readJob = null
        scope.coroutineContext.cancelChildren() // 取消所有协程任务
    }

    // ========= 权限检测 ========= //
    private fun checkBtConnectPermission(context: Context): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            ContextCompat.checkSelfPermission(
                context, Manifest.permission.BLUETOOTH_CONNECT
            ) == PackageManager.PERMISSION_GRANTED
        } else true
    }

    fun byteArrayToHexString(bytes: ByteArray): String {
        return bytes.joinToString(" ") { "%02X".format(it) }
    }
}